import {
  _decorator,
  Animation,
  Collider2D,
  Component,
  Contact2DType,
  EventTouch,
  Input,
  input,
  instantiate,
  IPhysics2DContact,
  Node,
  Prefab,
  Sprite,
  Vec3,
} from "cc";
import { RewardType, UIReward } from "./UIReward";
import { GameManager } from "../GameManager";
import { LifeUILayer } from "../LifeUILayer";
const { ccclass, property } = _decorator;

enum shootType {
  None,
  oneShoot,
  twoShoot,
}

@ccclass("UIPlayer")
export class UIPlayer extends Component {
  // 射击频率（间隔）
  @property
  shootRate: number = 0.3;
  shootTimer: number = 0;
  // 子弹预制体
  @property(Prefab)
  bulletPrefab1: Prefab = null;
  @property(Prefab)
  bulletPrefab2: Prefab = null;
  // 子弹发射位置
  @property(Node)
  bulletPos1: Node = null;
  @property(Node)
  bulletPos2: Node = null;
  @property(Node)
  bulletPos3: Node = null;
  // 子弹父节点
  @property(Node)
  bulletParent: Node = null;
  // 射击类型
  @property
  shootType: shootType = shootType.oneShoot;
  // 生命
  @property
  lifeCount: number = 3;
  // 动画
  @property(Animation)
  anim: Animation = null!;
  // 无敌时间
  @property
  invincibleTime: number = 1;
  invincibleTimer: number = 0; // 无敌时间
  isInvincible: boolean = false; // 是否无敌
  // 碰撞器
  collder: Collider2D = null;
  // 奖励物品：双弹模式奖励时间
  @property
  twoShootRewardTime: number = 5;
  twoShootRewardTimer: number = 0;
  // 生命条组件
  @property(LifeUILayer)
  lifeUILayer: LifeUILayer = null;
  // 是否可以控制主机
  private canControl: boolean = true;
  protected onLoad(): void {
    input.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);

    this.collder = this.node.getComponent(Collider2D);
    if (this.collder) {
      this.collder.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
    }
  }
  protected onDestroy(): void {
    input.off(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
    if (this.collder) {
      this.collder.off(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
    }
  }
  start() {
    this.lifeUILayer.onUpdateLifeNumber(this.lifeCount);
  }

  update(deltaTime: number) {
    this.shootTimer += deltaTime;
    // 双弹奖励时间判断
    if (this.shootType === shootType.twoShoot) {
      this.twoShootRewardTimer += deltaTime;
      if (this.twoShootRewardTimer >= this.twoShootRewardTime) {
        // 奖励时间到了就恢复单弹模式
        this.twoShootRewardTimer = 0;
        this.shootType = shootType.oneShoot;
      }
    }
    if (this.shootTimer >= this.shootRate) {
      this.shootTimer = 0;
      switch (this.shootType) {
        case shootType.oneShoot:
          this.onOneShoot();
          break;
        case shootType.twoShoot:
          this.onTwoShoot();
          break;
        default:
          break;
      }
    }

    if (this.isInvincible) {
      this.invincibleTimer += deltaTime;
      if (this.invincibleTimer >= this.invincibleTime) {
        this.isInvincible = false;
      }
    }
  }

  onBeginContact(
    selfCollider: Collider2D,
    otherCollider: Collider2D,
    contact: IPhysics2DContact | null
  ) {
    const reward = otherCollider.getComponent(UIReward);
    if (reward) {
      this.rewardContactHandle(reward);
    } else {
      this.enemyContactHandle();
    }
  }
  /**
   *
   * 当奖励物品最终被销毁时，JavaScript 的垃圾回收机制会自动处理 lastReward 引用的对象。
   *  所以不用手动释放内存。
   */
  lastReward: UIReward = null;
  rewardContactHandle(reward: UIReward) {
    if (this.lastReward === reward) return;
    this.lastReward = reward;
    // 奖励接触处理
    switch (reward.rewardType) {
      case RewardType.TwoShoot:
        this.twoShootRewardTimer = 0;
        this.shootType = shootType.twoShoot;
        break;
      case RewardType.Bomb:
        GameManager.getInstance().addBomb();
        break;

      default:
        break;
    }

    reward.getComponent(Collider2D).enabled = false;
    reward.getComponent(Sprite).enabled = false;
  }
  enemyContactHandle() {
    // 敌机接触处理
    if (this.isInvincible) return;
    this.isInvincible = true;
    this.invincibleTimer = 0;

    // this.lifeCount -= 1;
    this.changeLifeCount(-1);

    if (this.lifeCount > 0) {
      this.anim.play("Player_Hit");
    } else {
      this.anim.play("Player_Down");
    }

    if (this.lifeCount <= 0) {
      this.shootType = shootType.None;
      if (this.collder) {
        this.collder.enabled = false;
      }
    }
  }

  changeLifeCount(count: number) {
    this.lifeCount += count;
    this.lifeUILayer.onUpdateLifeNumber(this.lifeCount);
  }

  onOneShoot() {
    const bullet = instantiate(this.bulletPrefab1);
    const bulletPos = this.bulletPos1.getWorldPosition();
    this.bulletParent.addChild(bullet);
    bullet.setWorldPosition(bulletPos);
  }
  onTwoShoot() {
    const bulletPos1 = this.bulletPos2.getWorldPosition();
    const bulletPos2 = this.bulletPos3.getWorldPosition();
    const bullet1 = instantiate(this.bulletPrefab2);
    const bullet2 = instantiate(this.bulletPrefab2);
    this.bulletParent.addChild(bullet1);
    this.bulletParent.addChild(bullet2);
    bullet1.setWorldPosition(bulletPos1);
    bullet2.setWorldPosition(bulletPos2);
  }

  onTouchMove(event: EventTouch) {
    if (!this.canControl) return;
    if (this.lifeCount <= 0) return;

    let pos = this.node.position;
    let newPos = new Vec3(
      pos.x + event.getDeltaX(),
      pos.y + event.getDeltaY(),
      pos.z
    );

    if (newPos.x < -230) {
      newPos.x = -230;
    }
    if (newPos.x > 230) {
      newPos.x = 230;
    }
    if (newPos.y < -380) {
      newPos.y = -380;
    }
    if (newPos.y > 380) {
      newPos.y = 380;
    }
    this.node.setPosition(newPos);
  }

  setCanControl(canControl: boolean) {
    this.canControl = canControl;
  }
}
